package com.xunk.scene.controller;

import com.xunk.common.core.utils.StringUtils;
import com.xunk.common.core.web.domain.AjaxResult;

import com.xunk.common.redis.service.RedisService;
import com.xunk.scene.constant.SceneConstant;
import com.xunk.scene.mapper.SceneConditionWeatherMapper;
import com.xunk.scene.service.SceneService;
import com.xunk.scene.service.WeatherService;
import com.xunk.scene.threadpool.ThreadPools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.util.List;

/**
 * @ProjectName: xunk-scene
 * @Package: com.xunk.job.controller
 * @ClassName: XxlJonController
 * @Author: tangguangyuan
 * @Description: xxljob控制controller
 * @Date: 2021/4/22 14:27
 * @Version: 1.0
 */
@RestController
@RequestMapping(value = "/timer")
public class TimerController extends SceneController {
    private static final Logger log = LoggerFactory.getLogger(TimerController.class);

    @Autowired
    private SceneService sceneService;

    @Autowired
    private WeatherService weatherService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private SceneConditionWeatherMapper sceneConditionWeatherMapper;

    @Value("${scene.time-out}")
    private long SceneTimeOut;

    /**
     * 执行定时任务，先判断是否同时满足设备和生效时间条件，满足则执行设备动作
     * 设置redis锁，再天气场景执行成功后，设置锁，再规定时间内xxl-job再次发起执行定时任务时，不再执行
     *
     * @param sceneId
     * @return
     */
    @GetMapping(value = "/exec")
    public AjaxResult execCron(@RequestParam(value = "sceneId") long sceneId, @RequestParam(value = "isWeather") boolean isWeather) {
        log.info("开始执行定时场景：" + sceneId);
        //定时场景锁 key
        String lockKey = SceneConstant.SCENE_TIMER_LOCK + sceneId;
        AjaxResult ajaxResult = AjaxResult.error();
        try {
            boolean result = redisService.tryLock(lockKey, String.valueOf(sceneId), SceneTimeOut, false);

            if (result) {
                //判断是否满足场景执行条件
                boolean matchResult = false;
                try {
                    matchResult = sceneService.matchCondition(sceneId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (matchResult == false)
                    ajaxResult = AjaxResult.error(String.format("未满足该场景执行条件，场景ID：%d,执行失败", sceneId));

                //判断成功执行设备动作
                ajaxResult = sceneService.execSceneAction(String.valueOf(sceneId), StringUtils.EMPTY,true);
            } else {
                ajaxResult = AjaxResult.error("场景执行中或已执行完毕");
            }
        } finally {
            if (ajaxResult.isSuccess()) {
                log.info("定时场景执行成功：" + sceneId);
                //非天气自动添加的定时任务，执行完成后 释放锁
                if (!isWeather) {
                    redisService.unlock(lockKey, String.valueOf(sceneId));
                }
            } else {
                redisService.unlock(lockKey, String.valueOf(sceneId));
            }
            return ajaxResult;
        }

    }


    //定时执行天气条件的场景
    @GetMapping("/execWeather")
    public AjaxResult execWeatherCron() {
        List<Integer> sceneList = sceneConditionWeatherMapper.querySceneIdsfromConditionWeather();
        for (Integer sceneId:
             sceneList) {
            ThreadPools.executor.execute(new Thread(()->sceneService.execSceneAction(String.valueOf(sceneId),StringUtils.EMPTY,true)));
        }
        return AjaxResult.error();
    }

    /**
     * 调度中心调用此接口实现定时更新天气
     *
     * @return
     */
    @GetMapping(value = "/updateWeather")
    public AjaxResult updateWeather() {

        return weatherService.cacheWeather();
    }
}
